// 防抖函数高级版
function debounce1(fn, wait, immediate) {// immediate为true时，函数立即执行，否则等待wait时间后执行
  let timeout;// 定时器
  return function () {// 返回一个函数
    let context = this, args = arguments;// 保存this和参数
    let later = function () {// 延迟执行函数
      timeout = null;// 清除定时器
      if (!immediate) fn.apply(context, args);// 如果不是立即执行，则执行函数, 并传入当前方法的参数
      // apply()可以传入一个数组，将数组中的每一项作为参数传入函数
      // fn.apply(this,arguments) this指向当前对象，arguments是一个数组
      //fn接受的是fn(‘参数1’,‘参数2’,…)这种形式，而不是fn([‘参数1’,‘参数2’,…])这种形式
    };
    let callNow = immediate && !timeout;// 如果是立即执行，则不需要延迟执行
    clearTimeout(timeout);// 清除定时器
    timeout = setTimeout(later, wait);// 设置定时器
    if (callNow) fn.apply(context, args);// 如果是立即执行，则执行函数
  };
}


// 函数节流
export function throttle(fn, delay) {
  let timer = null;
  return function () {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this);
        timer = null;
      }, delay);
    }
  }
}

// 函数防抖
export function debounce(fn, delay) {
  let timer = null;
  return function () {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  }
}

// 1.防抖在连续的事件，只需触发一次回调的场景有：

// -- 搜索框搜索输入。只需用户最后一次输入完，再发送请求
// -- 手机号、邮箱验证输入检测
// -- 窗口大小resize。只需窗口调整完成后，计算窗口大小。防止重复渲染。

// 2.节流在间隔一段时间执行一次回调的场景有：

// -- 滚动加载，加载更多或滚到底部监听
// -- 搜索框，搜索联想功能